/*
 * @author Chris
 * @since 2023/2/6 17:11
 *
 * @brief    The project will ...
 *
 * @note     ...
 *
 * @warning  Do not to ...
 *
 * Change Logs:
 *   Date           Author       Notes
 *   2023/2/6     Chris        the first version
 */
#include "8052.h"

#define _nop_() __asm nop __endasm

#define IO_18B20 P3_2

void DelayX10us(unsigned char time) {
    do {
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
        _nop_();
    } while (time--);
}

__bit Get18B20Ack() {
    EA = 0;
    IO_18B20 = 0;
    DelayX10us(50);
    IO_18B20 = 1;
    DelayX10us(6);
    __bit ack = IO_18B20;
    while (!IO_18B20);
    EA = 1;
    return ~ack;
}

void Write18B20(unsigned char dat) {
    EA = 0;
    for (unsigned char mask = 0x01; mask != 0; mask <<= 1) {
        IO_18B20 = 0;
        _nop_();
        _nop_();
        IO_18B20 = (mask & dat) == 0 ? 0 : 1;
        DelayX10us(6);
        IO_18B20 = 1;
    }
    EA = 1;
}

unsigned char Read18B20() {
    EA = 0;
    unsigned char dat = 0;
    for (unsigned char mask = 0x01; mask != 0; mask <<= 1) {
        IO_18B20 = 0;
        _nop_();
        _nop_();
        IO_18B20 = 1;
        _nop_();
        _nop_();
        dat = dat | (IO_18B20 == 0 ? 0 : mask);
        DelayX10us(6);
    }
    EA = 1;
    return dat;
}

__bit Start18B20() {
    if (Get18B20Ack()) {
        Write18B20(0xCC);
        Write18B20(0x44);
    }
    return 1;
}

__bit Get18B20Temp(int *temp) {
    if (Get18B20Ack()) {
        Write18B20(0xCC);
        Write18B20(0xBE);
        unsigned char lsb = Read18B20();
        unsigned char msb = Read18B20();
        *temp = ((int) msb << 8) + lsb;
        return 1;
    }

    return 0;
}